//
//  Network.h
//  YanXiuWang
//
//  Created by 慧趣小歪 on 16/11/16.
//  Copyright © 2016年 小分队. All rights reserved.
//

#import "Reachability.h"

#define Network [NetworkManager shared]

@class Reachability;
@class RequestNormal;
@class ResponseNormal;

typedef RequestNormal * _Nonnull (^NET_URL)(NSString * _Nonnull url);
typedef RequestNormal * _Nonnull (^NET_GET)(NSDictionary * _Nonnull params);
typedef RequestNormal * _Nonnull (^NET_POST)(NSDictionary * _Nonnull params);
typedef RequestNormal * _Nonnull (^NET_POST_JSON)(NSString * _Nonnull json);
typedef RequestNormal * _Nonnull (^NET_POST_DATA)(NSData * _Nonnull data);
typedef RequestNormal * _Nonnull (^NET_POST_ARRAY)(NSArray<__kindof NSDictionary *> * _Nonnull array);
typedef RequestNormal * _Nonnull (^NET_HeaderField)(NSString * _Nonnull header, id _Nonnull value);

typedef void (^OnComplete)(ResponseNormal * _Nonnull task);
typedef void (^NET_PROGRESS_BLOCK)(NSProgress * _Nonnull progress);

typedef RequestNormal * _Nonnull (^NET_PROGRESS)(NET_PROGRESS_BLOCK _Nonnull progressBlock);

@interface NetworkQueue : NSObject

@property (nullable, nonatomic, strong) NSMutableArray<__kindof NSURLSessionTask *> *requests;
@property (nullable, nonatomic, strong) NSURLSessionTask *currentTask;

@property (nonnull, readonly, nonatomic) Reachability *hostReachability;
@property (nonnull, readonly, nonatomic) NSURLSession *defaultSession;
@property (assign, nonatomic) dispatch_once_t sessionOnceToken;


@property (nonnull, readonly, nonatomic) NET_URL request;

- (BOOL)completeURLSessionTask:(NSURLSessionTask * _Nonnull)task;

@end


@interface NetworkManager : NSObject

@property (nonnull, readonly, nonatomic) NetworkQueue *defaultQueue;
@property (nonnull, readonly, nonatomic) NET_URL request;
@property (nonnull, readonly, nonatomic) NSDate *serverDate;
@property (nonatomic, assign) NSTimeInterval timeOffset;

+ (nonnull NSString *)getParamsFromDictionary:(NSDictionary * _Nonnull)dict;
+ (nonnull NSMutableURLRequest *)getURLRequestWithTask:(RequestNormal * _Nonnull)task;

@end

#pragma mark - http 请求相关
@interface RequestNormal : NSObject

/** GET 模式提交参数  */
@property (nonatomic, copy, readonly) NET_GET _Nonnull get;
/** POST 模式提交参数  */
@property (nonatomic, copy, readonly) NET_POST _Nonnull post;
/** POST 模式提交参数  */
@property (nonatomic, copy, readonly) NET_POST_ARRAY _Nonnull postArray;
/** POST 模式提交参数  */
@property (nonatomic, copy, readonly) NET_POST_JSON _Nonnull postJSON;
/** POST 模式提交参数  */
@property (nonatomic, copy, readonly) NET_POST_DATA _Nonnull postData;
/** 模拟覆盖 HeaderField 头 */
@property (nonatomic, copy, readonly) NET_HeaderField _Nonnull header;

@property (nonatomic, weak) __kindof  NetworkQueue * _Nullable queue;

- (nonnull NSURLSessionTask*)commit:(OnComplete _Nonnull)completeBlock;

/** 其他回调扩展 */
@property (nonatomic, readonly) NSMutableDictionary * _Nonnull blockMap;

@end

#pragma mark - http 响应结果
@interface ResponseNormal : NSObject

@property (nonatomic, strong) NSDictionary * _Nonnull source;

@property (nonatomic, readonly) __kindof NSURLSessionTask * _Nonnull task;
@property (nonatomic, readonly) __kindof RequestNormal * _Nonnull request;
@property (nonatomic, readonly) NSURLRequest * _Nonnull urlRequest;
@property (nonatomic, readonly) NSString * _Nullable params;
@property (nonatomic, readonly) NSError * _Nullable error;
@property (nonatomic, readonly) NSData * _Nullable data;
@property (nonatomic, readonly) int stateCode;
@property (nonatomic, readonly) NSDate * _Nonnull serverDate;

@end

@interface NSURLSessionTask (Response)

@property (nonatomic, strong) __kindof ResponseNormal * _Nullable netResponse;

@end

@interface NSProgress (Percent)

@property (nonatomic, readonly) double progressPercent;

@end

#pragma mark - 单例相关
@interface NetworkManager (Once)

+ (nonnull instancetype)shared;

@end
